<template>
  <el-dialog
    :title="_transitionLanguages('button', 'permissionSetting')"
    v-model="dialogVisible"
    width="800px"
    top="2vh"
    :destroy-on-close="true"
    draggable
    :close-on-click-modal="false"
    @close="$emit('update:visible', false)"
  >
    <el-tabs v-model="activeName" class="demo-tabs">
      <el-tab-pane :label="_transitionLanguages('title', 'menusOperationAuthority')" name="first">
        <el-table
          v-loading="dataGrid.loading"
          :data="dataGrid.data"
          highlight-current-row
          height="500"
          border
          :span-method="objectSpanMethod"
        >
          <!-- 一级菜单 -->
          <el-table-column prop="name1" label="一级菜单" width="150">
            <template #default="{ row }">
              <el-checkbox v-model="row.checked1" :label="row.name1" @change="changeFirstMenu(row)" />
            </template>
          </el-table-column>

          <el-table-column prop="name2" label="二级菜单" width="150">
            <template #default="{ row }">
              <el-checkbox v-if="row.name2" v-model="row.checked2" :label="row.name2" @change="changeSecondMenu(row)" />
            </template>
          </el-table-column>

          <el-table-column prop="operateList" :label="_transitionLanguages('table', 'operation')">
            <template #default="{ row }">
              <span v-for="(operate, operateIndex) in row.operateList" :key="operateIndex" style="margin-right: 10px">
                <el-checkbox
                  v-if="operate.name"
                  v-model="operate.checked3"
                  :label="operate.name"
                  @change="changeOperateBtn(row)"
                />
              </span>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
    </el-tabs>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">{{ _transitionLanguages('button', 'cancel') }}</el-button>
        <el-button type="primary" @click="saveOperateMenu">
          {{ _transitionLanguages('button', 'confirm') }}
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import { PublicParams } from '@/api/interface/publicParams';

interface OpPermProps {
  visible: boolean;
  roleId: number | null;
}

interface TableItemProps {
  // 一级菜单id
  id1: number;
  // 二级菜单id
  id2: number;
  // 三级菜单id
  id: number;
  // 一级菜单是否选中
  checked1: boolean;
  // 二级菜单是否选中
  checked2: boolean;
  // 操作按钮是否选中
  checked3: boolean;
  // 一级菜单名称
  name1: string;
  // 二级菜单名称
  name2: string;
  // 操作按钮集合
  operateList: TableItemProps[];
  // 操作按钮数量
  operateBtnQuantity: number;
  // 二级菜单数量数量
  name2Quantity: number;
  // 操作类型
  actionType: string;
  // 对应权限码
  metaRole: string;
}

const $emit = defineEmits(['update:visible']);

// 接受父组件参数，配置默认值
const props = withDefaults(defineProps<OpPermProps>(), {
  visible: false,
  roleId: null
});
let dialogVisible = ref(props.visible);

let dataGrid = ref<any>({
  loading: false,
  data: []
});

watch(
  () => props.visible,
  val => {
    dialogVisible.value = val;
    if (val) {
      init();
    }
  }
);
watch(
  () => dialogVisible.value,
  val => {
    $emit('update:visible', val);
  }
);

// 语言转换
const _transitionLanguages = (v: string, l: string): string => {
  return transitionLanguages(v, l);
};

// 获取菜单列表
const init = async () => {
  if (!props.roleId) {
    elMessage('请选择角色', 'error');
    return;
  }

  Object.assign(dataGrid.value, {
    loading: true,
    data: []
  });

  const res = await promiseAllApi([permissionFindListByRoleId({ id: props.roleId }), permissionFindTreeList()]);

  const tableData: TableItemProps[] = getTableData(res[1]);
  const checkedData = res[0] || [];

  let name1s = [];
  let name2s = [];

  // 勾选对应的有的角色菜单
  for (let item of tableData) {
    if (checkedData.includes(item.id1)) {
      // 记录被选中的一级菜单
      item.checked1 = true;
    }
    // 记录被选中的二级菜单
    if (checkedData.includes(item.id2)) {
      item.checked2 = true;
    }
    for (let son of item.operateList) {
      // 记录被选中的操作按钮
      if (checkedData.includes(son.id)) {
        son.checked3 = true;
      }
    }
  }

  for (let item of tableData) {
    if (name1s.includes(item.name1)) {
      item.checked1 = true;
    }

    if (name2s.includes(item.name2)) {
      item.checked2 = true;
    }
  }

  // 因为表格合并特性 对一级菜单的勾选情况进行处理
  for (let item of tableData) {
    if (name1s.includes(item.name1)) {
      item.checked1 = true;
    }
  }
  mergeColumn(tableData, 'name1');

  Object.assign(dataGrid.value, {
    loading: false,
    data: tableData
  });
};

const getTableData = data => {
  let newData: TableItemProps[] = [];

  // 只获取有对应api请求的数据
  for (let item of data) {
    if (item?.children?.length) {
      for (let son of item.children) {
        if (son?.children?.length) {
          son.children.forEach(son => {
            son.checked3 = false;
          });
        }
        console.log(son.name, 'so==============');

        newData.push({
          id1: item.id,
          id2: son.id,
          id: null,
          checked1: false,
          checked2: false,
          checked3: false,
          name1: item.name,
          name2: son.name,
          operateBtnQuantity: son?.children?.length || 0,
          name2Quantity: item.children.length || 0,
          operateList: son?.children || [],
          actionType: item.actionType,
          metaRole: item.metaRole
        });
      }
    } else {
      newData.push({
        id1: item.id,
        id2: null,
        id: null,
        checked1: false,
        checked2: false,
        checked3: false,
        name1: item.name,
        name2: null,
        operateBtnQuantity: 0,
        name2Quantity: 0,
        operateList: [],
        actionType: item.actionType,
        metaRole: item.metaRole
      });
    }
  }

  return newData;
};

const activeName = ref('first');

const objectSpanMethod = ({ columnIndex, row }) => {
  if (columnIndex === 0) {
    return {
      rowspan: row.rowSpan,
      colspan: 1
    };
  }
};

/**
 * 设置保存菜单的参数
 */
const setSaveParams = () => {
  let saveParams: PublicParams.ResBindingId = {
    bindingIds: [],
    targetId: props.roleId
  };
  console.log(dataGrid.value.data, 'dataGrid.value.data');

  for (let item of dataGrid.value.data) {
    // 一级菜单选中
    if (item.checked1 && !saveParams.bindingIds.includes(item.id1)) {
      console.log(item.id1);

      saveParams.bindingIds.push(item.id1);
    }

    // 二级菜单选中
    if (item.checked2 && !saveParams.bindingIds.includes(item.id2)) {
      console.log(item.id2);
      saveParams.bindingIds.push(item.id2);
    }

    // 操作按钮选中
    for (let son of item.operateList) {
      if (son.checked3) {
        saveParams.bindingIds.push(son.id);
      }
    }
  }

  return saveParams;
};

// 保存操作的菜单
const saveOperateMenu = () => {
  const data = setSaveParams();
  permissionPermissionIdsBindingRoleId(data);
  $emit('update:visible', false);
  elMessage();
};

// 一级菜单值变化
const changeFirstMenu = (item: TableItemProps) => {
  const { name1, checked1 } = item || {};

  dataGrid.value.data.forEach(item => {
    if (item.name1 === name1) {
      if (item.id2) {
        // 把对应状态同步到后面所有的菜单
        item.checked2 = checked1;
      }

      if (item?.operateList?.length) {
        for (let son of item?.operateList) {
          son.checked3 = checked1;
        }
      }
    }
  });
};

// 二级菜单值变化
const changeSecondMenu = (item: TableItemProps) => {
  const { name2, name1, checked2 } = item;
  let count = 0;

  for (let v of dataGrid.value.data) {
    // 三级菜单跟随二级菜单变换
    if (v.name2 === name2) {
      v.operateList.forEach(son => {
        son.checked3 = checked2;
      });
    }

    // 记录对应一级菜单选中的二级菜单
    if (v.name1 === name1) {
      if (v.checked2) {
        count++;
      }
    }
  }

  // 改变一级菜单状态
  for (let v of dataGrid.value.data) {
    if (v.name1 === name1) {
      v.checked1 = count > 0;
    }
  }
};

// 对操作栏进行修改
const changeOperateBtn = item => {
  const { name2, name1 } = item;

  // 如果有选中那么二级菜单，一级菜单需要同步勾选
  for (let son of dataGrid.value.data) {
    // 勾选对应的二级菜单
    if (son.name2 === name2) {
      son.checked2 = true;
    }

    // 把对应的一级菜单全部勾选 (合并表格后勾选第一个数据的状态就可以了，，不想去判断了，全部勾选上让一级菜单显示勾选)
    if (son.name1 === name1) {
      son.checked1 = true;
    }
  }
};
</script>
